package com.example.config;

import com.example.handler.TokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Arrays;

/**
 * Author: Zeran
 * Date: 2024-06-07 19:28
 * Desc:
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {

	@Autowired
	private TokenInterceptor tokenInterceptor;

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		// 设置允许跨域的路径
		registry.addMapping("/**")
				// 设置允许跨域请求的域名
				// 这里写的*表示允许所有域，实际情况可能有以下几种形式
				// .allowedOrigins("http://app.example.com:80"); 写全了，个人认为最正规的写法，但是更喜欢用下面这种
				// .allowedOrigins("http://app.example.com");
				// 只写了协议和域名，端口使用http默认的80，https的话是443，应该是最常用的写法（因为一般都使用默认的端口）
				// .allowedOrigins("http://123.123.123.123:8888"); 前端服务器没有域名的情况下，也可以使用ip地址
				.allowedOriginPatterns("*")
				// 是否允许cookie
				.allowCredentials(true)
				// 设置允许的请求方式
				.allowedMethods("GET", "POST", "DELETE", "PUT")
				// 设置允许的header属性
				.allowedHeaders("*")
				// 跨域允许时间，用于设置预检请求（OPTIONS方法）的缓存时间（单位秒）。设置为
				// 3600（即1小时）表示浏览器可以缓存这个CORS响应信息1小时，期间对同一源的跨域请求不再发送预检请求，直接使用缓存结果，从而提高性能。
				.maxAge(3600);
	}

	@Bean
	public CorsConfigurationSource corsConfigurationSource() {
		CorsConfiguration configuration = new CorsConfiguration();
		configuration.addAllowedOrigin("*"); // 允许所有来源, 可以根据需求改成指定的域名
		configuration.addAllowedOriginPattern("*");
		configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); // 只允许4种请求方式
		configuration.addAllowedHeader("*"); // 允许所有请求头
		configuration.setAllowCredentials(true); // 允许携带cookie

		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration); // 对所有URL生效
		return source;
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 添加拦截器
		registry.addInterceptor(tokenInterceptor)
				.addPathPatterns("/**")
				// 排除静态资源路径
				.excludePathPatterns("/doc.html", "/favicon.ico", "/webjars/**", "/static/**")
				// 排除swagger api请求
				.excludePathPatterns("/v3/api-docs/**", "/swagger-ui/**")
				// 排除请求服务器静态资源
				.excludePathPatterns("/uploads/**")
				// 排除404页面传递
				.excludePathPatterns("/404","/error");
		;
	}
}
